package com.tuling.bzg.mybatis.spring;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.classreading.MetadataReader;

import java.io.IOException;
import java.util.Set;

/**
 * 扫描器，扫描指定报下的mapper接口
 * */
public class BzgClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {

    public BzgClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }

    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> definitionHolders = super.doScan(basePackages);

        definitionHolders.forEach(v -> {
            GenericBeanDefinition beanDefinition = (GenericBeanDefinition)v.getBeanDefinition();
            Class<?> beanClass = null;
            try {
                beanClass = Class.forName(beanDefinition.getBeanClassName());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanClass);
            beanDefinition.setBeanClass(BzgMapperFactoryBean.class); //替换为对应的代理bean的工厂bean
            beanDefinition.setAutowireMode(Autowire.BY_TYPE.value());  // 设置bean的自动注入,也就是自动调用属性set方法
        });
        return definitionHolders;
    }

    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface();
    }

    @Override
    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        return super.isCandidateComponent(metadataReader);
    }
}
